/*=+--+=#=+--     Unmanned Aerial System Management Software      --+=#=+--+=#*\
|          Copyright (C) 2011 Regents of the University of Colorado.           |
|                             All Rights Reserved.                             |

     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2 as
     published by the Free Software Foundation.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.

            Jack Elston                       Cory Dixon                        
|           elstonj@colorado.edu              dixonc@colorado.edu              |
|                                                                              |
\*=+--+=#=+--                 --+=#=+--+=#=+--                    --+=#=+--+=#*/

/***********************************************************************
 *
 * FILENAME:
 * queue.h
 *
 * PURPOSE:
 *   Implemnts a fifo queue for floats
 *
 * CREATED:
 * 11/2000 by Cory Dixon
 *
 * LAST MODIFIED:
 * $Author: dixonc $
 * $Date: 2005/07/13 21:00:06 $
 * $Revision: 1.3 $
 *
 ***********************************************************************/

#ifndef __cplusplus
ERROR: Must use C++ for Queue.
#endif

#ifndef _QUEUE_H
# define _QUEUE_H

#include <stdlib.h>
#include <unistd.h>
#include <fstream>

#ifndef VXWORKS
# ifndef _POSIX_SEMAPHORES
ERROR:_POSIX_SEMAPHORES is not defined
# else
#  include <bits/pthreadtypes.h>
#  include <semaphore.h>
# endif
#else
# undef Free	// some lame ass defined Free as a macro in vxWorks
#endif

using namespace::std;

typedef float QueueType;

class Queue {

	public:
		Queue(size_t numElements = 512);
		~Queue();

		bool Push(const QueueType * element, size_t numElements = 1);
		size_t Pop(QueueType * element = NULL, size_t numElements = 1);
		QueueType* const Peek(size_t elementInd = 0);

		size_t Size() const;
		void SetSize(size_t numElements );

		size_t Free();
		size_t Used();

		QueueType Max() const;
		QueueType Min() const;
		QueueType Average() const;
		void findMin();
		void findMax();

		bool saveToFile(const char * fileName);

	private:

		QueueType *Memory;
		size_t NumElements;

		volatile unsigned int PushInd;
		volatile unsigned int PopInd;
		volatile size_t NumUsed;

		struct MinMaxVal {
			unsigned int ind;
			QueueType val;
		} minVal, maxVal;

#ifndef VXWORKS
		sem_t Mutex;
#endif

		size_t IncInd(size_t ind, size_t numInc = 1);
};

#endif
